-- SPDX-License-Identifier: GPL-3.0-or-later
---@class EndLessPractice: Object
---@field public reward_cfg table<string, number>
---@field public pdl_tmpskills string
---@field public panduola_call number
local EndLessPractice = class("EndLessPractice")

function EndLessPractice:initialize()
  --白名单武将池
  self.all_generals = {}
  self.clone_generals = {}
  self.camps = {lord = 1,loyalist = 1,rebel = 2}
end

function EndLessPractice:initData(player,data)   --初始化数据
  self.hardmodel = data.hardmodel
  self.layowner = player
  self.room = player.room
  self.layer = data.i_layer
  self.totallayer = data.t_layer
  self.maxctiwin = data.maxctiwin
  self.laygetskill_n = data.laygetskill_n  --层主每过几关获得技能
  self.layownskills = data.layownskills
  self.rewd_intval = data.rewd_intval
  self.godboss = data.godboss
  self.rulename = data.rulename
  

  self.reward_cfg = {}     --过关奖励选项列表
  self.pdl_tmpskills = {}  --潘多拉临时技能
  self.panduola_call = 0   --潘多拉开启次数
  self.curctiwin = 0        --连胜次数
  self.meetpyrate = 0
  self.meetpylayer = 0
  self.getpdlskillnum = 0
  self.curboss = nil

  self:initOplayerData(data)
  self:initSkills()
  self:initLayer()
  self:configureAI()
  self:initShop(data.shopitems)
end

function EndLessPractice:initShop(shopdata)
  self.shop_items = {}
  self.shopitems = table.clone(shopdata)
  local atkskills,defskills = {},{}
  for i=1,10 do --药水，装备
    table.insert(self.shop_items,self.shopitems[i])
  end
  for i=11,26 do --进攻技
    table.insert(atkskills,self.shopitems[i])
  end
  for i=27,#self.shopitems do --防御技
    table.insert(defskills,self.shopitems[i])
  end
  table.insertTable(self.shop_items,table.random(atkskills,3))
  table.insertTable(self.shop_items,table.random(defskills,3))
  table.insert(self.shop_items,"Exist")
end

function EndLessPractice:upShopRandSkills(num)
  local atkskills,defskills = {},{} 
  for i=11,26 do --进攻技
    if not table.contains(self.shop_items,self.shopitems[i]) then
      table.insert(atkskills,self.shopitems[i])
    end
  end
  for i=27,#self.shopitems do --防御技
    if not table.contains(self.shop_items,self.shopitems[i]) then
      table.insert(defskills,self.shopitems[i])
    end
  end
  table.removeOne(self.shop_items,"Exist")
  table.insertTable(self.shop_items,table.random(atkskills,num))
  table.insertTable(self.shop_items,table.random(defskills,num))
  table.insert(self.shop_items,"Exist")
end

function EndLessPractice:gainRandGold()
  local room = self.room
  local layer = self.layer
  table.forEach(self.otherplayers,function (op)
    local min = math.ceil(layer/10)
    local max = math.floor(min+math.random(2,3)+0.5)
    local randgold = math.floor(math.random(min,max)+0.5)
    -- local randgold = 500
    room:addPlayerMark(op,"@gold_num",randgold)
    room:doBroadcastNotify("ShowToast",Fk:translate(op.general).."金币+"..randgold)
  end)
end

function EndLessPractice:getShopEquips(equip,from)
  local room = self.room
  local geteid
  local name = string.sub(equip,4)
  for _, id in ipairs(Fk:getAllCardIds()) do
    local card = Fk:getCardById(id, true)
    if card.trueName == name then
      geteid = id
      break
    end
  end
  if geteid then
    room:obtainCard(from,geteid,true,fk.ReasonJustMove)
    return true
  else
    room:doBroadcastNotify("ShowToast", "买不到？似乎没开【浪包】扩展包？")
  end
  return false
end

function EndLessPractice:getShopSkills(skill,from)
  local room = self.room
  local name = string.sub(skill,4)
  if table.find(from.player_skills,function(s) return s.trueName==name end) then return false end
  room:handleAddLoseSkills(from, name, nil, false)
  return true
end

function EndLessPractice:buyShopItem(who,chs,price,goldnum,item_name)
  local room = self.room
  local item_str = string.sub(item_name,1,3)
  local trans = Fk:translate(item_name)
  trans = string.gsub(trans,"(%arg金币)","")
  if goldnum - price >= 0 then
    local ret
    if item_str == "sp_" then
      local name = string.sub(item_name,4)
      local mark = name == "redpotion" and "@slash_dmg" or "@trick_dmg"
      room:setPlayerMark(who,mark,who:getMark(mark) * 2)
      ret = true
    end
    if item_str == "st_" then
      ret = self:getShopEquips(item_name,who)
    end
    if item_str == "sk_" then
      ret = self:getShopSkills(item_name,who)
    end
    if ret then 
      room:setPlayerMark(who,"@gold_num",goldnum - price) 
      room:doBroadcastNotify("ShowToast", Fk:translate(who.general) .."购买"..trans)
      table.removeOne(self.shop_items,item_name..":::"..price)
    else
      room:doBroadcastNotify("ShowToast", Fk:translate(who.general) .."购买失败")
    end
  else
    room:doBroadcastNotify("ShowToast", Fk:translate(who.general) .."买不起"..trans)
  end 
end

function EndLessPractice:cellSelfSkills(player)
  local room = self.room
  local pdlskills = self.pdl_tmpskills[tostring(player.id)]
  local equipskills = {}
  local cellskills = {}
  if #player.player_cards[Player.Equip] > 0 then
    for _,eid in ipairs(player.player_cards[Player.Equip]) do
      local card = Fk:getCardById(eid)
      if card and card.equip_skill then table.insert(equipskills,card.equip_skill.name) end
      if card.name == "yx_yvxi" then table.insert(equipskills,"l_feiyang") table.insert(equipskills,"l_bahu") end
    end
  end
  local dera_skills = {zhengnan = {"wusheng","dangxian","zhiman"},baobian = {"tiaoxin","paoxiao","shensu"}}
  local except_skills
  for _,s in ipairs(player.player_skills) do
    if dera_skills[s.trueName] then
      except_skills = dera_skills[s.trueName]
    end
    if  not string.find(pdlskills,s.name) and not table.contains(equipskills,s.name) and (not except_skills and true or not table.contains(except_skills,s.trueName)) then
      table.insert(cellskills,s.name)
    end
  end
  if #cellskills == 0 then room:doBroadcastNotify("ShowToast", "无可售技能") return end
  if #cellskills > 0 then
    table.insert(cellskills,"Exist")
    while #cellskills > 1 do
      local chs = room:askForChoice(player, cellskills, "#puyuanShop-cellskills", "#puyuanShop-cellskills")
      if chs == "Exist" then return end
      room:addPlayerMark(player,"@gold_num",math.floor(math.random(20,30)+0.5))
      room:handleAddLoseSkills(player, "-"..chs, nil, false)
      table.removeOne(cellskills,chs)
    end
  end
end

function EndLessPractice:enterPYShop(player)
  local room = self.room
  if #self.shop_items < 2 then room:doBroadcastNotify("ShowToast", "铁匠铺东西卖光了") return end
  while #self.shop_items > 1 do
    local chs = room:askForChoice(player, self.shop_items, "#puyuanShop-buyeuips", "#puyuanShop-buyeuips")
    if chs == "Exist" then break end
    local goldnum = player:getMark("@gold_num")
    local price_pos = string.find(chs,":%d")
    local name_pos = string.find(chs,":")
    local price = tonumber(string.sub(chs,price_pos+1))
    local name = string.sub(chs,1,name_pos-1)
    -- print(goldnum,price_pos,price,name)
    -- dbg()
    self:buyShopItem(player,chs,price,goldnum,name)
    if #self.shop_items < 2 then room:doBroadcastNotify("ShowToast", "铁匠铺东西卖光了") return end
  end
end

function EndLessPractice:meetPuYuan()
  local room = self.room
  if self.layer % 10 == 0 then
    self.meetpyrate = 0 --遇见浦沅概率
    self.meetpylayer = 0 --每10层只能遇见一次浦沅
  end
  if self.layer > 10 and self.layer < 51 then
    self.meetpyrate = self.meetpyrate + 0.1
  end
  if self.layer == 51 and self.hardmodel == "godmodel" then
    self.meetpyrate = 1
  end
  -- self.meetpyrate = 1 --测试
  if math.random() < self.meetpyrate and self.meetpylayer == 0 then
    self.meetpyrate = 0
    self.meetpylayer = math.floor(self.layer / 10)
    self:upShopRandSkills(2)
    local chc = {"Exist","pyshop_buyitems","pyshop_cellskills"}
    if #chc > 1 then
      table.forEach(self.otherplayers,function (op)
        while #chc > 1 do
          local chs = self.room:askForChoice(op, chc, "#puyuanShop-choice", "#puyuanShop-choice")
          if chs == "Exist" then break end
          if chs == "pyshop_buyitems" then
            self:enterPYShop(op)
          end
          if chs == "pyshop_cellskills" then
            self:cellSelfSkills(op)
          end
        end
      end)
    end
  end
end

function EndLessPractice:getOPlayers(who,rm)
  local room = rm or self.room
  local nocamps = {}
  local layerfriends = {}
  for _, player in ipairs(room.alive_players) do
    if player.id ~= who.id then
      if self.camps[player.role] ~= self.camps[who.role] then
        table.insert(nocamps,player)
      else
        table.insert(layerfriends,player)
      end
    end
  end
  if not self.layowner or self.camps[self.layowner.role] == self.camps[who.role] then
    self.otherplayers = nocamps
    self.layerfriends = layerfriends
  end
  return nocamps
end

function EndLessPractice:getLDieFriends()
  local nocamps = {}
  for _, player in ipairs(self.room.players) do
    if player.id ~= self.layowner.id then
      if player.dead and self.camps[player.role] == self.camps[self.layowner.role] then
        table.insert(nocamps,player)
      end
    end
  end
  return nocamps
end

function EndLessPractice:getDiePlayers()
  local dead_t = {}
  for _, player in ipairs(self.room.players) do
    if player.dead and player.role == "rebel" then
      table.insert(dead_t,player.general)
    end
  end
  return dead_t
end

function EndLessPractice:getPyGodWeapon()
  local puyuan_weapons = {"red_spear", "quenched_blade", "poisonous_dagger", "water_sword", "thunder_blade"}
  local py_equips,py_weapons={},{}
  for i, item in ipairs(self.shop_items) do
    if string.startsWith(item,"st_") then
      local name_pos = string.find(item,":")
      local name = string.sub(item,4,name_pos-1)
      table.insert(py_equips,name)
    end
  end
  if #py_equips == 0 then return py_equips end
  for _,pyep in ipairs(py_equips) do
    if table.contains(puyuan_weapons,pyep) then
      table.insert(py_weapons,pyep)
    end
  end
  return py_weapons
end

function EndLessPractice:removePyGodWeapon(name)
  local rmname
  for i, ep in ipairs(self.shop_items) do
    if string.startsWith(ep,name) then
      rmname = ep
      break
    end
  end
  if rmname then table.removeOne(self.shop_items,rmname) end
end

function EndLessPractice:changeLayer(layer)
  self.layer = self.layer + layer
end

function EndLessPractice:getLayer()
  return self.layer
end

function EndLessPractice:addContiWin(n)
  self.curctiwin = self.curctiwin + n
end

function EndLessPractice:handleContiWin()
  local room = self.room
   if self.layer == 51 then
    room:doBroadcastNotify("ShowToast","你已进入【通神之路】，准备迎接诸神的挑战")
  end
  if self.layer == 71 then
    room:doBroadcastNotify("ShowToast","恭喜你通关70层，你已经胜利了！")
  end
  if self.layer == 71 then
    room:doBroadcastNotify("ShowToast","接下来请欣赏最后的战歌")
  end
  if self.curctiwin == self.maxctiwin-1 then
    room:doBroadcastNotify("ShowToast", "层主的凝视。连胜太多越难，再连胜结束你的当前阶段")
  end
  if (self.curctiwin >= self.maxctiwin or self.curboss) and room.current.role == "rebel" then
    self:endWhoPhase(room.current,GameEvent.ChangeHp)
  end
  if self.layer >= 40 then self.maxctiwin = 4 end
end

function EndLessPractice:setContiWin(n)
  self.curctiwin = n
end

function EndLessPractice:getContiWin()
  return self.curctiwin
end

function EndLessPractice:addPdlCall(n)
  self.panduola_call = self.panduola_call + n
end

function EndLessPractice:getPdlCall()
  return self.panduola_call
end

function EndLessPractice:initOplayerData(data)
  local otherplayers = self.otherplayers
  for _, p in ipairs(otherplayers) do
    self.reward_cfg[tostring(p.id)] = data.rewards
    self.pdl_tmpskills[tostring(p.id)] = ""
    self.room:setPlayerMark(p,"curlayerphase",1)
    self.room:setPlayerMark(p,"@gold_num",data.initgold+math.floor(math.random(2,5)+0.5))
  end
end

function EndLessPractice:initSkills()
  local layowner = self.layowner
  local otherplayers = self.otherplayers
  if #otherplayers > 1 then
    self.room:handleAddLoseSkills(layowner, "wjsl_zhenta|os_ex__paoxiao", nil, false)
    for _, p in ipairs(otherplayers) do --玩家获得咆哮和铸甲
      self.room:handleAddLoseSkills(p, "os_ex__paoxiao|wjsl_zhujia", nil, false)
    end
    if self.layerfriends and #self.layerfriends > 0 then
      for _, p in ipairs(self.layerfriends) do --层主忠臣队友获得咆哮
        self.room:handleAddLoseSkills(p, "os_ex__paoxiao", nil, false)
      end
    end
    self.room:drawCards(layowner, #otherplayers,self.rulename)
    layowner.hp = layowner.hp + 1
    layowner.maxHp = layowner.maxHp + 1
    self.room:setPlayerProperty(layowner, "hp", layowner.hp)
    self.room:setPlayerProperty(layowner, "maxHp", layowner.maxHp)
  else
    -- self.room:handleAddLoseSkills(layowner, "wjsl_buding", nil, false)
  end
  for _, p in ipairs(self.room.players) do
    if p.role ~= "lord" then
      self.room:handleAddLoseSkills(p, "wjsl_zhenfen", nil, false)
    end
  end
end

function EndLessPractice:initLayer()
  self.room:setPlayerMark(self.layowner,"@wj_layer",self.layer)
  if self.hardmodel == "godmodel" then
    for _, p in ipairs(self.room.players) do
      if p.role ~= "lord" then
      self.room:setPlayerMark(p,"@@godmodel",1)
      end
    end
  end
end

function EndLessPractice:updateLayer(who,mark)
  local layer = self.layer
  if self.layer == 71 then
    self.room:setPlayerMark(who,mark,"Max")
  else
  self.room:setPlayerMark(who,mark,layer)
  end
end

function EndLessPractice:configureAI()
  -- for _, p in ipairs(self.room.players) do
  --   if p.id < 0 then
  --     p.ai = nil
  --     p.ai = LangAI:new(p)
  --   end
  -- end
end

function EndLessPractice:removeRelateSkills(who)
  local og = Fk.generals[who.general]
  local to_rm = table.map(og.related_skills, Util.NameMapper)
  table.insertTable(to_rm, og.related_other_skills)
  self.room:handleAddLoseSkills(who, table.concat(table.map(to_rm, function(s) return "-" .. s end), "|"), nil, true)
end

function EndLessPractice:changeGeneral(who,allgens,hasboss)
  local newgeneral = hasboss and Fk.generals[hasboss] or table.remove(allgens or self.all_generals,1)
  if not newgeneral then return end
  self.room:changeHero(who, newgeneral.name, true, false, true)
  self.room:revivePlayer(who, false)
  self.room:setPlayerProperty(who, "kingdom", Fk.generals[newgeneral.name].kingdom)
  --self.room:askForChooseKingdom({who})
  return newgeneral.name
end

function EndLessPractice:notifyLayer(mark)
  local otherplayers = self.otherplayers
  local layer = self.layer
  for _, pr in ipairs(otherplayers) do
    self.room:setPlayerMark(pr,mark,layer)
  end
end

function EndLessPractice:updateMax(who,cal_add,mes)
    who.hp = who.hp + cal_add
    who.maxHp = who.maxHp + cal_add
    self.room:setPlayerProperty(who, "hp", who.hp)
    self.room:setPlayerProperty(who, "maxHp", who.maxHp)
    if mes then
      self.room:doBroadcastNotify("ShowToast", mes)
    end
end

function EndLessPractice:getLaySkills(who)
  local layer = self.layer
  for s, l in pairs(self.layownskills) do
    if not who:hasSkill(s) and layer >= l then
      self.room:handleAddLoseSkills(who, s, nil, false)
    end
  end
end

function EndLessPractice:removeOldSkills(newgeneral,who)
  local layer = self.layer
  local gen = Fk.generals[newgeneral]
  local otherskills = gen.other_skills
  local rm_skills = {}
  local new_gen_skills = table.map(gen.skills,function (ski)
    return ski.name
  end)
  if otherskills and #otherskills > 0 then
    table.insertTableIfNeed(new_gen_skills,otherskills)
  end
  for _, skill in ipairs(who.player_skills) do
    --过滤永久技能wjsl_zhenta|paoxiao
    if skill.name ~= "wjsl_zhenta" and skill.name ~= "os_ex__paoxiao" and not table.contains(new_gen_skills,skill.name) then
      --过滤关卡技能
      if not self.layownskills[skill.name] or layer < self.layownskills[skill.name] then
        table.insert(rm_skills,"-"..skill.name.."|")
      end
    end
  end
  if #rm_skills > 0 then
    local loseskills = table.concat(rm_skills,"")
    self.room:handleAddLoseSkills(who, loseskills, nil, false)
  end
end

function EndLessPractice:bury(who,exceptlist)
  who:setSkillUseHistory("")
  who:setCardUseHistory("")
  who:throwAllCards()
  if exceptlist then
    for mark,v in pairs(who.mark) do
      if not table.contains(exceptlist,mark) then
        self.room:setPlayerMark(who, mark, 0)
      end
    end
  else
    who:throwAllMarks()
  end
  who:clearPiles()
  who:reset()
end

function EndLessPractice:getRskiNum()
  local getskill_n = math.floor(self.layer / self.laygetskill_n)
  if getskill_n > 0 then
    return getskill_n 
  else
    return 0
  end
end

function EndLessPractice:getRandSkills(n,all_generals,who,istmp)
  local getskills_t = {}
  local trans_skinames = ""
  while #getskills_t < n do
    local randg = table.random(all_generals)
    local skills_name = {}
    for _, ski in ipairs(randg.skills) do
        if ski.frequency < Skill.Limited then
            table.insert(skills_name,ski.name)
        end
    end
    if #skills_name > 0 then
      local rand_skill = table.random(skills_name)
      local skilltrueName = Fk.skills[rand_skill].trueName
      local canget = table.every(who.player_skills,function (ski)
        if ski.trueName ~= skilltrueName then
          return true
        end
      end)
      if canget then
        if #trans_skinames > 0 then
          trans_skinames = trans_skinames.. "、"
        end
        trans_skinames = trans_skinames..Fk:translate(rand_skill)
        table.insert(getskills_t,rand_skill)
        if istmp then
          self.pdl_tmpskills[tostring(who.id)] = self.pdl_tmpskills[tostring(who.id)]..rand_skill.."|"
        end
      end
    end
  end
  local skills = table.concat(getskills_t,"|")
  skills = string.sub(skills,1,-1)
  self.room:handleAddLoseSkills(who, skills, nil, false)
  if istmp then
    self.room:doBroadcastNotify("ShowToast",Fk:translate(who.general).."获得魔盒技能："..trans_skinames)
    return getskills_t[1]
  else
    self.room:doBroadcastNotify("ShowToast",Fk:translate(who.general).."获得技能："..trans_skinames)
  end
end

function EndLessPractice:drawByRelife(who)
  local layer = self.layer
  local players_hands = 0
  local otherplayers = self.otherplayers
  table.forEach(otherplayers,function (p)
    players_hands = players_hands + #p.player_cards[Player.Hand]
  end)
  local layer_hands = math.ceil(layer / 10) * 2 + self.curctiwin * self.curctiwin
  local extra_draw = 3 * math.ceil((#otherplayers / (#self.room.alive_players-#otherplayers))) + layer_hands + (self.curboss and layer_hands or 0)
  if players_hands > #otherplayers * 6 then
    extra_draw = extra_draw + math.ceil((players_hands - extra_draw) / 4)
  end
  self.room:drawCards(who, extra_draw,self.rulename)
  --单人玩家摸牌
  if #otherplayers == 1 then
    local alivep = otherplayers[1]
    self.room:drawCards(alivep, 3 + math.ceil(layer / 10),self.rulename)
  end
end

function EndLessPractice:otherPlayersDraw(num)
  table.forEach(self.otherplayers,function (p)
    self.room:drawCards(p, num,self.rulename)
  end)
end

function EndLessPractice:endWhoPhase(who,phase,isforce)
  -- if who.id == self.layowner.id and not isforce then return end
  local current = who.room.logic:getCurrentEvent()
  local who_phase = current:findParent(phase)
  if not who_phase then return end
  local phase_event = who_phase:findParent(GameEvent.Phase)
  if not phase_event then return end
  if #self.otherplayers > 1 and not isforce then
    self.layowner:gainAnExtraTurn(true)
  end
  self.room:doBroadcastNotify("ShowToast", Fk:translate(who.general).."结束当前阶段")
  who_phase:addExitFunc(function()
    phase_event:shutdown()
  end)
end

function EndLessPractice:callPanduola(who,call_n)
  if self.panduola_call >= call_n then 
    self.panduola_call = -9999   
    self:removeRelateSkills(who)
    local whoname = "l__panduola"
    self.room:changeHero(who, whoname, true, false, true)
    self.room:setPlayerProperty(who, "kingdom", Fk.generals[whoname].kingdom)
    self.room:askForChooseKingdom({who})
    self:removeOldSkills(whoname,who)
    self.room:drawCards(who,10,self.rulename)
    self.room:doBroadcastNotify("ShowToast", "魔盒变得狂躁起来，张开血盆大口向你扑过来...")
  end
end

--重置潘多拉技能
function EndLessPractice:resetPdlSkills(chcname)
  local otherplayers = self.otherplayers
  for _, p in ipairs(otherplayers) do
    local mark = p:getMark("@pdlbox")
    local tmpskills = self.pdl_tmpskills[tostring(p.id)]
    if #tmpskills > 0 and mark > 0 then
      local skills_t = tmpskills:split("|")
      table.removeOne(skills_t,"")
      table.insert(skills_t,"Cancel")
      local resetskills,skillsname = {},{}
      local resetskis = {["#rstskills_1"]=5,["#rstskills_2"]=7,["#rstskills_3"]=10,["#rstskills_4"]=12,["#rstskills_5"]=15}
      local resetnum = 1
      while resetskis["#rstskills_"..resetnum] and p:getMark("@gold_num") >= resetskis["#rstskills_"..resetnum] do
        local resetstr = "#rstskills_"..resetnum
        local chs = self.room:askForChoice(p, skills_t, resetstr, resetstr,true)
        if chs == "Cancel" then break end
        self.room:handleAddLoseSkills(p, "-"..chs, nil, false)
        self.room:doBroadcastNotify("ShowToast", Fk:translate(p.general) .."失去魔盒技能："..Fk:translate(chs))
        table.removeOne(skills_t,chs)
        table.removeOne(skills_t,"Cancel")
        if #skills_t > 0 then
          self.pdl_tmpskills[tostring(p.id)] = table.concat(skills_t,"|")
          self.pdl_tmpskills[tostring(p.id)] = self.pdl_tmpskills[tostring(p.id)].."|"
        else
          self.pdl_tmpskills[tostring(p.id)] = ""
        end
        local getskill = self:getRandSkills(1,self.clone_generals,p,true)
        if not getskill then break end
        self.room:removePlayerMark(p,"@gold_num",resetskis["#rstskills_"..resetnum])
        resetnum = resetnum + 1
        table.insert(skills_t,getskill)
        table.insert(skills_t,"Cancel")
      end
    end
  end
end

--随机的奖励选项
function EndLessPractice:randRewardSel(who)
  local layer,room = self.layer,self.room
  --玩家奖励随机选项（按照cfg配置随机每个选项）
  local reward_n_sel = function ()
    for i = 1, #self.rewd_intval do
      if layer < self.rewd_intval[i][1] then
        return {self.rewd_intval[i][3],self.rewd_intval[i][2]}
      end
    end
  end
  local rwd_n_sel = reward_n_sel()  --奖励（总共项|选择次数）
  if not rwd_n_sel then return end
  local sel_n = rwd_n_sel[2]        --奖励可以选择次数 
  --寻找不重复技能
  local skill_n = 0
  local rand_choices = function (reward_cfg)
    local choices = {} 
    while #choices < rwd_n_sel[1] do
      local rand = math.random()
      local forward = 0
      for i, v in pairs(reward_cfg) do
        local last = v
        if rand >= forward and rand < last + forward  then
          -- 技能可以多个存在
          if i ~= "skills" and table.contains(choices,i) then
            break
          end
          table.insert(choices,i)
          if i == "skills" then
            skill_n = skill_n + 1 --列表中技能个数
          end
          break
        end
        forward = forward + last
      end
    end
    return choices
  end
  local cfg = self.reward_cfg[tostring(who.id)]
  --选项加工替换其中的skills
  local chc = rand_choices(cfg)     --选项列表（技能是skill需要被真的技能名替换）      
  local rand_skills = {}
  local prohib_forn = 0
  while skill_n > 0 and #rand_skills < skill_n do
    local randg = table.random(self.all_generals)
    local skills_name = {}
    for _, sk in ipairs(randg.skills) do
      if sk.frequency < Skill.Limited then
        table.insert(skills_name,sk.name)
      end
    end
    local rand_skill = table.random(skills_name)
    if rand_skill and not who:hasSkill(rand_skill) then
      table.insert(rand_skills,rand_skill)
    end
    --防止死循环
    if prohib_forn > 300 then
      room:doBroadcastNotify("ShowToast", "敌人将池过少，游戏结束")
      room:gameOver("rebel")
      return
    end
    prohib_forn = prohib_forn + 1
  end
  --技能名字替换skills
  for i = 1, #chc do
    if chc[i] == "skills" and #rand_skills > 0 then
      chc[i] = table.remove(rand_skills,1)
    end
  end
  return chc,sel_n
end

--选项(潘多拉)
function EndLessPractice:choiceByPdl(who,chs,name)
  local luckyman = who
  if chs == "disCard" then
    self:throwHalfHands(luckyman,name)
  elseif chs == "turnOver" then
    self:turnOver(luckyman)
  elseif chs == "tianQian" then
    self:tianQian(luckyman,name)
  elseif chs == "getShenQi" then
    self:getShenQi(who,name)
  elseif chs == "tmpSkills" then
    local randmark = table.random({1,1,1,1,1,1,2,2,2,3})
    self:addBoxMark(who,"@pdlbox",randmark)
  end
end

--潘多拉印记技能
function EndLessPractice:addBoxMark(who,mark,num)
  if self.layer == 50 and self.hardmodel == "godmodel" then
    self.room:addPlayerMark(who,mark,num)
    self:getRandSkills(num,self.clone_generals,who,true)
    self.room:doBroadcastNotify("ShowToast",Fk:translate(who.general).."获得魔盒印记+"..num)
    self.room:addPlayerMark(who,mark,num)
    self:getRandSkills(num,self.clone_generals,who,true)
    self.room:doBroadcastNotify("ShowToast",Fk:translate(who.general).."获得魔盒印记+"..num)
    self.room:addPlayerMark(who,mark,num)
    self:getRandSkills(num,self.clone_generals,who,true)
    self.room:doBroadcastNotify("ShowToast",Fk:translate(who.general).."获得魔盒印记+"..num)
    self.room:addPlayerMark(who,mark,num)
    self:getRandSkills(num,self.clone_generals,who,true)
    self.room:doBroadcastNotify("ShowToast",Fk:translate(who.general).."获得魔盒印记+"..num)
    self.room:addPlayerMark(who,mark,num)
    self:getRandSkills(num,self.clone_generals,who,true)
    self.room:doBroadcastNotify("ShowToast",Fk:translate(who.general).."获得魔盒印记+"..num)
    self.room:addPlayerMark(who,mark,num)
    self:getRandSkills(num,self.clone_generals,who,true)
    self.room:doBroadcastNotify("ShowToast",Fk:translate(who.general).."获得魔盒印记+"..num)
    self.room:addPlayerMark(who,mark,num)
    self:getRandSkills(num,self.clone_generals,who,true)
    self.room:doBroadcastNotify("ShowToast",Fk:translate(who.general).."获得魔盒印记+"..num)
    self.room:addPlayerMark(who,mark,num)
    self:getRandSkills(num,self.clone_generals,who,true)
    self.room:doBroadcastNotify("ShowToast",Fk:translate(who.general).."获得魔盒印记+"..num)
    self.room:addPlayerMark(who,mark,num)
    self:getRandSkills(num,self.clone_generals,who,true)
    self.room:doBroadcastNotify("ShowToast",Fk:translate(who.general).."获得魔盒印记+"..num)
    self.room:addPlayerMark(who,mark,num)
    self:getRandSkills(num,self.clone_generals,who,true)
    self.room:doBroadcastNotify("ShowToast",Fk:translate(who.general).."获得魔盒印记+"..num)
  else
  self.room:addPlayerMark(who,mark,num)
  self:getRandSkills(num,self.clone_generals,who,true)
  self.room:doBroadcastNotify("ShowToast",Fk:translate(who.general).."获得魔盒印记+"..num)
  end
end

--丢弃一半手牌
-- function EndLessPractice:throwHalfHands(who,name)
--   local handcards = who.player_cards[Player.Hand]
--   if #handcards > 1 then
--     local dis_cs = table.random(handcards,math.floor(#handcards / 2))
--     self.room:throwCard(dis_cs, name, who, who)
--   end
--   self.room:doBroadcastNotify("ShowToast","潘多拉张开獠牙大嘴冲向了"..Fk:translate(who.general).."，他因为感到恐惧随机丢弃一半手牌...")
-- end

--天谴
-- function EndLessPractice:tianQian(who,name)
--   self.room:damage{to = who,damage = math.ceil(who.hp/2),damageType = fk.ThunderDamage,skillName = name}    
--   self.room:doBroadcastNotify("ShowToast", "潘多拉打了个哈欠..顺便吟唱张角的闪电"..Fk:translate(who.general).."不小心成为天命之子...")
-- end

--翻面
-- function EndLessPractice:turnOver(who)
--   who:turnOver() 
--   self.room:doBroadcastNotify("ShowToast","潘多拉喷出奇怪东西砸晕了"..Fk:translate(who.general).."仔细一看是gk的木马...")
-- end

--神器
-- function EndLessPractice:getShenQi(who,name)
--   if self.shenqi_n >= 2 then
--     self.room:doBroadcastNotify("ShowToast", "潘多拉神器空空如也~或许是被哪个窃贼偷光了...")
--     self.room:drawCards(who,2,name)
--     return
--   end
--   if math.random() < self.panduola_rate[tostring(who.id)] then
--     self.room:doBroadcastNotify("ShowToast", "潘多拉提醒你有神器。但它告诉你你今天运气不好，多回去等等，下次一定！")
--     self.room:drawCards(who,2,name)
--     return
--   end
--   for _, id in ipairs(Fk:getAllCardIds()) do
--     local card = Fk:getCardById(id)
--     if card.name == "shsfzjg" or card.name == "shttk" then
--         if self.room:getCardArea(id) == Card.Void then
--             self.room:moveCards({
--                 ids = {id},
--                 fromArea = Card.Void,
--                 to = who.id,
--                 toArea = Card.PlayerHand,
--                 moveReason = fk.ReasonJustMove,
--                 proposer = who.id,
--                 skillName = name,
--             })
--             self.shenqi_n = self.shenqi_n + 1
--             self.room:doBroadcastNotify("ShowToast", "神器！吕布的神器！潘多拉一脸欧皇看着你...")
--             break
--         end
--     end
--   end 
-- end

function EndLessPractice:removeLayerBoss(who)
  if self.curboss then 
    if #self.godboss == 0 then
      self.curboss = nil
      return
    end
    table.removeOne(self.godboss,self.curboss)
    if not who or who.id == self.layowner.id then
      self.curboss = nil
      return
    end
    local bossskills = table.map(Fk.generals[self.curboss].skills,function (s)
      return s.name
    end)
    local chs = self.room:askForChoice(who, bossskills, "#getBossSkills-choice", "#getBossSkills-choice",true) 
    self.room:handleAddLoseSkills(who, chs, nil, false)
    self.curboss = nil
    local bossgold = 40 * math.ceil(self.layer / 10)
    self.room:addPlayerMark(who,"@gold_num",bossgold)
    self.room:doBroadcastNotify("ShowToast",Fk:translate(who.general).."击杀神将金币+"..bossgold)
  end
end

function EndLessPractice:getLayerBoss()
  -- local step = math.floor(self.layer / 10)
  if self.curboss then return self.curboss end
  local step_n = self.layer
  local bossname = nil
  if step_n % 10 == 0  then
    if #self.godboss > 0 then
      bossname = table.random(self.godboss)
      if self.layer < 50 then
        local clone_t = table.clone(self.godboss)
        if self.layer == 10 then
          table.removeOne(clone_t,"joy__godguanyu")
          bossname = table.random(clone_t)
        end
      end
      if self.layer == 70 then
        bossname = "joy__godzhangfei"
      end
      self.curboss = bossname
    else
      bossname = "joy__godzhangfei"
      self.curboss = bossname
    end
  elseif step_n < 70 and step_n > 50 then
    bossname = table.random(self.godboss)
    self.curboss = bossname
  elseif step_n == self.totallayer then
    bossname = "joyo__xiaoshan"
  end
  return bossname
end

--复活玩家(死亡时候)
function EndLessPractice:relifePlayer(general)
  for _, player in ipairs(self.room.players) do
    if player.general == general and player.dead then
      self.room:revivePlayer(player, false)
      self.room:setPlayerMark(player, "curlayerphase",self.layer)
      self.room:drawCards(player, 4 + (math.floor(self.layer/10) * 2),self.rulename)
      break
    end
  end
end

--复活层主忠臣人机队友(死亡时候)
function EndLessPractice:reLayerFriends(ldiefriends)
  local room = self.room
  local otherplayers = self.otherplayers
  for _, player in ipairs(ldiefriends) do
    self:bury(player)
    self:removeRelateSkills(player)
    local newgeneral = self:changeGeneral(player)
    if not newgeneral then
      room:doBroadcastNotify("ShowToast", "将池耗尽")
      room:gameOver("rebel")
      return
    end
    --删除复活前技能
    self:removeOldSkills(newgeneral,player)
    --刷新最大maxhp与hp
    local maxhpcfg = {4,3,2}
    local basic = maxhpcfg[#otherplayers]
    local cal_add = math.floor(self.layer / (basic and basic or 2))
    -- cal_add = math.floor(cal_add / 3)
    if cal_add > 0 then
      self:updateMax(player,cal_add)
    end
    --每过n关获得随机技能
    local n = self:getRskiNum()
    -- n = math.floor(n/2)
    if n > 0 then
      self:getRandSkills(n,self.clone_generals,player,false)
    end
    local ctw = self.curctiwin + 1
    room:drawCards(player, 4 + (math.floor(self.layer/10)*2) + ctw * 2,self.rulename)
  end
end

--关卡奖励
function EndLessPractice:layerRewards(reset)
  local otherplayers = self.otherplayers
  local room = self.room
  for _, p in ipairs(otherplayers) do
    local chc,sel_n = self:randRewardSel(p)
    if not chc then break end
    --守护天使
    local angelmark = p:getMark("@@guardangle")
    if angelmark == 0 and math.random() < 0.1 then
      table.remove(chc,math.floor(math.random(1,#chc)+0.5))
      table.insert(chc,"guard_angel")
    end
    --有死亡加入选项
    local deadPlayers = self:getDiePlayers()
    if #deadPlayers > 0 then
      table.insert(chc,"relife")
    end
    local retstr,retgold = "rsetrwd",0
    if reset then 
      sel_n = 1 
    else
      if self.layer <= 20 then
        retstr = retstr.."_1"
        retgold = 20
      elseif self.layer > 20 and self.layer <= 40 then
        retstr = retstr.."_2"
        retgold = 30
      else
        retstr = retstr.."_3"
        retgold = 40
      end
      if p:getMark("@gold_num") >= retgold then
        table.insert(chc,retstr)
      end
    end
    --奖励可以多选 
    for i = 1, sel_n do
      local sel_chs = room:askForChoice(p, chc, self.rulename, "#skills-choice", true)
      if sel_chs == "maxhp" then
        if self.layer == 50 and self.hardmodel == "godmodel" then
          local randv = math.random(15,25)
          self:updateMax(p,randv,Fk:translate(p.general).."选择了最大体力值+"..randv)
        else
          local randv = math.random() < 0.2 and 3 or table.random({1,2,1})
          self:updateMax(p,randv,Fk:translate(p.general).."选择了最大体力值+"..randv)
        end
      elseif sel_chs == "lingxin" then
        if self.layer == 50 and self.hardmodel == "godmodel" then
          local randv = math.random(5,15)
          room:addPlayerMark(p,"@df_lingxin",randv)
          room:doBroadcastNotify("ShowToast", Fk:translate(p.general).."选择了凌心+"..randv)
        else
        local randv = math.random() < 0.2 and 3 or table.random({1,2,1,1})
        room:addPlayerMark(p,"@df_lingxin",randv)
        room:doBroadcastNotify("ShowToast", Fk:translate(p.general).."选择了凌心+"..randv)
        end
      elseif sel_chs == "shieldnum" then
        if self.layer == 50 and self.hardmodel == "godmodel" then
          local randv = math.random(2,5)
          room:addPlayerMark(p,"@shieldnum",randv)
          room:doBroadcastNotify("ShowToast", Fk:translate(p.general).."选择了护甲+"..randv)
        else
          local randv = math.random() > 0.1 and 1 or 2
          room:addPlayerMark(p,"@shieldnum",randv)
          room:doBroadcastNotify("ShowToast", Fk:translate(p.general).."选择了护甲+"..randv)
        end
      elseif sel_chs == "magicbox" then
        self:addPdlCall(1) -- 开启潘多拉次数+1
        self:choiceByPdl(p,"tmpSkills",self.rulename)
      elseif sel_chs == "angelbless" then
        if p:isWounded() then
          room:recover({who = p,num = p:getLostHp(),recoverBy = p,skillName = self.rulename})
        end
        room:drawCards(p, p.maxHp,self.rulename)
        local randmark = table.random({"@slash_dmg","@trick_dmg","@gold_num","@df_lingxin","@shieldnum"})
        if randmark ~= "@gold_num" then
          room:addPlayerMark(p,randmark,1)
          room:doBroadcastNotify("ShowToast",Fk:translate(p.general).."选择了天使祝福，随机获得"..Fk:translate(randmark).."1")
        else
          local rand_gold = math.floor(math.random(10,20)*math.ceil(self.layer/10)+0.5)
          room:addPlayerMark(p,randmark,rand_gold)
          room:doBroadcastNotify("ShowToast",Fk:translate(p.general).."选择了天使祝福，随机获得"..Fk:translate(randmark)..rand_gold)
        end
      elseif sel_chs == "slash_dmg_sel" or sel_chs == "trick_dmg_sel" then
        if self.layer == 50 and self.hardmodel == "godmodel" then
          local strdmg = string.gsub(sel_chs,"_sel","")
          local n = math.random(2,3)
          room:addPlayerMark(p,"@"+strdmg,n)
          local str = sel_chs == "slash_dmg_sel" and "杀造成伤害+ " or "锦囊造成伤害+ "
          room:doBroadcastNotify("ShowToast", Fk:translate(p.general).."选择了"..str..n)
        else
          local strdmg = string.gsub(sel_chs,"_sel","")
          room:addPlayerMark(p,"@"+strdmg,1)
          local str = sel_chs == "slash_dmg_sel" and "杀造成伤害+1" or "锦囊造成伤害+1"
          room:doBroadcastNotify("ShowToast", Fk:translate(p.general).."选择了"..str)
        end
      elseif sel_chs == "relife" then
        if #deadPlayers == 0 then return end
        local relifechs = room:askForChoice(p, deadPlayers, self.rulename, "#relife-choice")
        self:relifePlayer(relifechs)
      elseif sel_chs == "guard_angel" then
        room:setPlayerMark(p,"@@guardangle",1)
        room:doBroadcastNotify("ShowToast", Fk:translate(p.general).."选择了守护天使")
      elseif sel_chs == "gaingold" then
        if self.layer == 50 and self.hardmodel == "godmodel" then
          local goldnum = math.random(30,70)
          room:addPlayerMark(p,"@gold_num",goldnum)
          room:doBroadcastNotify("ShowToast", Fk:translate(p.general).."获得金币+"..goldnum)
        else
          local goldnum = math.ceil(math.random(math.ceil(self.layer/10)*2+40,self.layer < 30 and 60 or 70))
          room:addPlayerMark(p,"@gold_num",goldnum)
          room:doBroadcastNotify("ShowToast", Fk:translate(p.general).."获得金币+"..goldnum)
        end
      elseif string.startsWith(sel_chs,"rsetrwd") then
        room:removePlayerMark(p,"@gold_num",retgold)
        self:layerRewards(true)
      else
        room:handleAddLoseSkills(p, sel_chs, nil, false)
        room:doBroadcastNotify("ShowToast", Fk:translate(p.general).."选择了技能："..Fk:translate(sel_chs))
      end
      table.removeOne(chc,sel_chs)
    end
  end
end

return EndLessPractice